<template>
  <div class="container">
    <h1 class="h1">DIFF算法模拟器</h1>
    <!-- 真实DOM -->
    <div class="wrapper dom-wrapper">
      <div class="title" style="line-height: 50px">真实DOM</div>
      <div class="box">
        <div class="drag-wrapper">
          <draggable
            class="drag"
            v-model="domList"
            :options="{ group: { name: 'itxst', pull: 'clone' }, sort: true }"
            animation="300"
          >
            <transition-group class="group">
              <div
                class="item"
                v-for="(item, index) in domList"
                :key="item.value"
              >
                {{ item.label }}
                <div class="close" @click="removeNode(index)">X</div>
              </div>
            </transition-group>
          </draggable>
        </div>
      </div>
    </div>

    <!-- 旧DOM树 -->
    <div class="wrapper old-wrapper">
      <div class="title" style="margin-top: 38px">旧Virtual DOM</div>
      <div class="box">
        <div class="drag-wrapper">
          <el-tooltip effect="dark" content="oldStartIndex" placement="top">
            <div
              class="icon oldStartIndex"
              :style="{ left: 70 * oldStartIndex + 5 + 'px' }"
            ></div>
          </el-tooltip>
          <el-tooltip effect="dark" content="oldEndIndex" placement="top">
            <div
              class="icon oldEndIndex"
              :style="{ left: 70 * oldEndIndex + 25 + 'px' }"
            ></div>
          </el-tooltip>
          <draggable
            class="drag"
            v-model="oldList"
            :options="{ group: { name: 'itxst', pull: 'clone' }, sort: true }"
            animation="300"
          >
            <transition-group class="group">
              <div
                class="item"
                :class="{ isUndf: item.label === 'U' }"
                v-for="(item, index) in oldList"
                :key="item.value"
              >
                {{ item.label }}
                <div class="undf" @click="undfNode(index)">-</div>
              </div>
            </transition-group>
          </draggable>
        </div>
      </div>
    </div>

    <!-- 新DOM树 -->
    <div class="wrapper new-wrapper">
      <div class="title" style="line-height: 50px">新Virtual DOM</div>
      <div class="box">
        <div class="drag-wrapper">
          <el-tooltip effect="dark" content="newStartIndex" placement="bottom">
            <div
              class="icon newStartIndex"
              :style="{ left: 70 * newStartIndex + 5 + 'px' }"
            ></div>
          </el-tooltip>
          <el-tooltip effect="dark" content="newEndIndex" placement="bottom">
            <div
              class="icon newEndIndex"
              :style="{ left: 70 * newEndIndex + 25 + 'px' }"
            ></div>
          </el-tooltip>
          <draggable
            class="drag"
            v-model="newList"
            :options="{ group: { name: 'itxst', pull: 'clone' }, sort: true }"
            animation="300"
          >
            <transition-group class="group">
              <div class="item" v-for="item in newList" :key="item.value">
                {{ item.label }}
              </div>
            </transition-group>
          </draggable>
        </div>
      </div>
    </div>

    <!-- 操作台 -->
    <div class="work-wrapper">
      <!-- 计数器 -->
      <div class="index-wrapper">
        <div class="index-item">
          <div class="index-label">oldStartIndex:</div>
          <div class="index-value">
            <el-input-number
              v-model="oldStartIndex"
              size="small"
            ></el-input-number>
          </div>
        </div>
        <div class="index-item">
          <div class="index-label">oldEndIndex:</div>
          <div class="index-value">
            <el-input-number
              v-model="oldEndIndex"
              size="small"
            ></el-input-number>
          </div>
        </div>
        <div class="index-item">
          <div class="index-label">newStartIndex:</div>
          <div class="index-value">
            <el-input-number
              v-model="newStartIndex"
              size="small"
            ></el-input-number>
          </div>
        </div>
        <div class="index-item">
          <div class="index-label">newEndIndex:</div>
          <div class="index-value">
            <el-input-number
              v-model="newEndIndex"
              size="small"
            ></el-input-number>
          </div>
        </div>
      </div>
      <div class="data-wrapper">
        <el-button type="primary" size="small" @click="randomData"
          >随机生成</el-button
        >
        <el-button type="warning" size="small" @click="reset">重置</el-button>
        <div style="margin-bottom: 10px"></div>
        <el-tooltip effect="dark" content="两两对比" placement="bottom">
          <el-button type="primary" size="small" plain @click="setting(1)"
            >案例1</el-button
          >
        </el-tooltip>
        <el-tooltip effect="dark" content="通过key匹配" placement="bottom">
          <el-button type="primary" size="small" plain @click="setting(2)"
            >案例2</el-button
          >
        </el-tooltip>
        <el-tooltip effect="dark" content="其他情况" placement="bottom">
          <el-button type="primary" size="small" plain @click="setting(3)"
            >案例3</el-button
          >
        </el-tooltip>
      </div>
    </div>
  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  name: "HelloWorld",
  components: {
    draggable,
  },
  data() {
    return {
      oldStartIndex: 0,
      oldEndIndex: 0,
      newStartIndex: 0,
      newEndIndex: 0,
      list: ["A", "B", "C", "D", "E", "F", "G", "H", "I"],
      domList: [
        // {
        //   label: "A",
        //   value: 1,
        // }, ...
      ],
      oldList: [],
      oldTemp: [],
      newList: [],

      temp: {
        1: {
          old: ["A", "B", "D", "F", "E", "C", "G"],
          new: ["A", "C", "E", "B", "G"],
        },
        2: {
          old: ["A", "B", "D", "C"],
          new: ["A", "D", "F", "E", "G"],
        },
        3: {
          old: ["E", "G", "F", 'D'],
          new: ["G", "E", "D", "C", "I"],
        },
      },
    };
  },
  created() {
    this.randomData();
  },
  methods: {
    init(domList, newList) {
      this.domList = [...domList];
      this.oldList = [...domList];
      this.oldTemp = [...domList]; // 重置时使用
      this.newList = [...newList];
      this.oldStartIndex = 0;
      this.newStartIndex = 0;
      this.oldEndIndex = this.oldList.length - 1;
      this.newEndIndex = this.newList.length - 1;
    },
    randomData() {
      this.init(this.createDomTree(), this.createDomTree());
    },
    reset() {
      this.domList = [...this.oldTemp];
      this.oldList = [...this.oldTemp];
      this.oldStartIndex = 0;
      this.newStartIndex = 0;
      this.oldEndIndex = this.oldList.length - 1;
      this.newEndIndex = this.newList.length - 1;
    },
    setting(n) {
      if (this.temp[n]) {
        this.init(
          this.temp[n].old.map((item, index) => {
            return {
              label: item,
              value: index + 1,
            };
          }),
          this.temp[n].new.map((item, index) => {
            return {
              label: item,
              value: index + 1,
            };
          })
        );
      } else {
        this.$message.error("没有该模板");
      }
    },
    removeNode(index) {
      this.domList.splice(index, 1);
    },
    undfNode(index) {
      this.oldList.splice(index, 1, {
        label: "U",
        value: Math.random(),
      });
    },
    createDomTree() {
      let len = Math.ceil(Math.random() * 5) + 2; // 随机设置新数组的长度
      let list = [...this.list];
      let arr = [];
      for (let i = 0; i < len; i++) {
        let length = list.length;
        let item = list.splice(Math.floor(Math.random() * length), 1);
        arr.push({
          label: item[0],
          value: i + 1,
        });
      }
      return arr;
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background-color: #efefef;
}
h1 {
  margin: 0;
  color: #333;
}
.wrapper {
  margin: 20px 0;
  display: flex;
}
.dom-wrapper {
  margin-bottom: 50px;
}
.drag-wrapper {
  position: relative;
}
.old-wrapper .drag {
  padding-top: 30px;
}
.new-wrapper .drag {
  padding-bottom: 30px;
}
.title {
  width: 120px;
  margin-right: 50px;
  line-height: 30px;
  font-weight: bold;
  font-family: 宋体;
  color: #333;
}
.box {
  width: 800px;
}
.drag {
  /* border: 1px solid #ccc; */
}

.icon {
  position: absolute;
  width: 25px;
  height: 25px;
  background-size: contain;
  transition-duration: 0.2s;
}
.newStartIndex {
  bottom: 0;
  left: 0;
  background-image: url("../assets/newStart.png");
}
.newEndIndex {
  bottom: 0;
  right: 0;
  background-image: url("../assets/newEnd.png");
}
.oldStartIndex {
  top: 0;
  left: 0;
  background-image: url("../assets/oldStart.png");
}
.oldEndIndex {
  top: 0;
  right: 0;
  background-image: url("../assets/oldEnd.png");
}

.group {
  width: 100%;
  display: flex;
  align-items: center;
  /* justify-content: center; */
}

.item {
  width: 50px;
  height: 50px;
  text-align: center;
  line-height: 50px;
  border-radius: 50%;
  font-size: 20px;
  background-color: #42b983;
  /* border: 1px solid #42b983; */
  color: #fff;
  margin-right: 20px;
  cursor: pointer;
  position: relative;
}
.isUndf {
  background-color: #ccc !important;
}
.item:last-child {
  margin: 0;
}
.item:hover .close {
  display: block;
}
.item:hover .undf {
  display: block;
}
.close {
  display: none;
  position: absolute;
  top: -5px;
  right: -5px;
  width: 15px;
  height: 15px;
  font-size: 10px;
  text-align: center;
  line-height: 15px;
  background-color: #f56c6c;
  color: #fff;
  border-radius: 50%;
  transition-duration: 0.2s;
}
.undf {
  display: none;
  position: absolute;
  top: -5px;
  right: -5px;
  width: 15px;
  height: 15px;
  font-size: 12px;
  text-align: center;
  line-height: 12px;
  background-color: #999;
  color: #fff;
  border-radius: 50%;
  font-weight: bold;
  transition-duration: 0.2s;
}
/* 操作台 */
.work-wrapper {
  margin-top: 50px;
  border-radius: 10px;
  background-color: #fff;
  width: 600px;
  box-shadow: 1px 3px 10px 1px #ccc;
  padding: 20px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}
.index-wrapper {
  width: 100%;
  flex-wrap: wrap;
  display: flex;
  margin-bottom: 10px;
}
.index-item {
  display: flex;
  margin-bottom: 10px;
  margin-right: 15px;
}
.index-label {
  width: 120px;
  line-height: 30px;
  text-align: center;
  margin-right: 10px;
}
</style>
